<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="../../jquery-3.3.1.js"></script>
</head>

<body>
    <script>
        window.onload = function () {
            (function () {
                // 一般的异步调用
                var wait = function () {
                    var task = function () {
                        console.log("执行完成");
                        // 执行所有的操作
                        // 1
                        // ...
                    }
                    setTimeout(task, 1000);
                }
                wait();

                // 使用jquery 中的 deferred 实现异步调用
                var deferredDemo = function () {
                    var dtd = $.Deferred();
                    var wait = function (deferred) {
                        var task = function () {
                            console.log("执行完成");

                            // 成功 返回
                            deferred.resolve();
                            // 失败返回
                            // deferred.reject();
                        }
                        setTimeout(task, 1000);

                        // wait 返回结果
                        // return deferred;
                        // 返回deferred.promoise(); 可以进一步优化异步调用
                        return deferred.promise();
                    }
                    // 最终返回 wait函数执行结果
                    return wait(dtd);
                }

                var d = deferredDemo();
                // 加入在这儿强制执行了d.reject() 那么后面的走向就会发生改变 造成不必要的后果 
                // 所以dtd.resolve dtd.reject 与 dtd.then dtd.done dtd.fail 应该分开执行  各司其职
                // d.reject();
                // d.then(function () {
                //     console.log("ok 1");
                // }, function () {
                //     console.log("err 1");
                // }).then(function () {
                //     console.log("ok 2");
                // }, function () {
                //     console.log("err 2");
                // }).then(function () {
                //     console.log("ok 3");
                // }, function () {
                //     console.log("err 3");
                // })

                // 避免在这里调用d.reject(); 会引起严重后果却不容易检查到的bug  可以在wait函数返回dtd.promise()
                //这样一来调用xxx.reject()就会报错 让我们及时查到bug 和避免使用
                var w = deferredDemo();
                // w.reject(); 报错 w is not a function
                $.when(w).then(function () {
                    console.log("ok 1");
                }, function () {
                    console.log("err 1");
                }).then(function () {
                    console.log("ok 2");
                }, function () {
                    console.log("err 2");
                }).then(function () {
                    console.log("ok 3");
                }, function () {
                    console.log("err 3");
                })
            })()
        }
    </script>
</body>

</html>